/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data;

import datenbank.*;
import java.rmi.*;
import java.sql.*;
import java.util.*;



/**
 *
 * @author Daniel
 */
public class VerwaltungImpl extends java.rmi.server.UnicastRemoteObject implements Verwaltung {

    private TischMapper tiMapper;
    private BestellungMapper beMapper;
    private ProduktMapper prMapper;
    private ZuordnungMapper zuMapper;

    public VerwaltungImpl(TischMapper tischMapper, BestellungMapper bestellungMapper, ProduktMapper produktMapper, ZuordnungMapper zuordnungMapper) throws RemoteException {
        super();
        this.tiMapper = tischMapper;
        this.beMapper = bestellungMapper;
        this.prMapper = produktMapper;
        this.zuMapper = zuordnungMapper;
    }


    /**
     * Die addProdukt Methode legt ein neues Produkt in der Datenbank an.
     * Dafür bekommt sie als Parameter das Objekt des Produkts, welches in der
     * Datenbank angelegt werden soll.
     * Sie überprüft dann ob es die Bezeichnung bereits gibt. Falls nicht wird es eingetragen, andernfalls wird
     * eine Fehlermeldung angezeigt
     * @param pr ist das Produkt, das angelegt werden soll
     * @return das Produkt, das angelegt wurde, falls die Bezeichnung noch nicht vergeben wurde
     * @throws RemoteException
     */
    public Produkt addProdukt(Produkt pr) throws RemoteException {

        if (this.comparePRbezeichnung(pr) && !pr.get_bezeichnung().isEmpty()) {
            return prMapper.insert(pr); //Speichert das Produkt
        } else {
            throw new RemoteException("Die Bezeichnung ist bereits vorhanden oder es wurde keine Bezeichnung eingegeben!");   //falls der Name bereits verwendet wird wird diese Exception geworfen
        }

    }

    /**
     * Diese Methode speichert eine Änderung bei einem Produkt in der Datenbank
     * ab. Dabei wird überprüft ob die Bezeichnung bereits vorhanden ist und ansonsten
     * wird die Änderung gespeichert. Sollte die Bezeichnung vorhanden sein, wird eine Remote Exception geworfen.
     * @param x ist das geänderte Produkt
     * @return das geänderte Produkt wird auch wieder zurückgegeben und in die Datenbank gespeichert
     * @throws RemoteException
     */
    public Produkt update(Produkt x) throws RemoteException {

        if (comparePRbezeichnung(x)) {
            return prMapper.update(x);
        } else {
            throw new RemoteException("Bezeichnung ist bereits vorhanden! Bitte andere wählen!");

        }

    }

    /**
     * Die Methode löscht ein Produkt aus der Datenbank, falls dieses in keiner
     * Bestellung mehr vorhanden ist. Sollte das Produkt noch in einer Bestellung vorhanden sein,
     * wird eine RemoteException geworfen.
     * @param x das Produkt, welches gelöscht werden soll
     * @throws RemoteException
     */
    public void delete(Produkt x)throws RemoteException {
        try {
            if (zuMapper.existsZuordnung(x)==false) {
                prMapper.delete(x);
            }else {
                  throw new RemoteException("Das Produkt ist noch in einer Bestellung enthalten und kann nicht gelöscht werden!");
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Die addTisch Methode legt ein neuen Tisch in der Datenbank an.
     * Dafür bekommt sie als Parameter das Objekt des Tischs, welches in der
     * Datenbank angelegt werden soll.
     * Sie überprüft dann ob es die Tisch Nummers bereits gibt. Falls nicht wird es eingetragen, andernfalls wird
     * eine Fehlermeldung angezeigt
     * @param ti ist das Tisch, das angelegt werden soll
     * @return der Tisch, der angelegt wurde, falls die Tisch Nummer noch nicht vergeben wurde
     * @throws RemoteException
     */
    public Tisch addTisch(Tisch ti) throws RemoteException {
        int vergleich = ti.get_tisch_nr();
        if (this.compareTInummer(ti) && (vergleich != 0)) {
            return tiMapper.insert(ti); //Speichert den Tisch
        } else {
            throw new RemoteException("Die Tisch Nummer ist bereits vorhanden oder es wurde keine eingegeben!");   //falls die Tisch Nummer bereits verwendet wird wird diese Exception geworfen
        }

    }

    /**
     * Diese Methode speichert eine Änderung bei einem Tisch in der Datenbank
     * ab. Dabei wird überprüft ob die Tisch Nummer bereits vorhanden ist und ansonsten
     * wird die Änderung gespeichert. Sollte die Tisch Nummer bereits vorhanden sein, wird eine Remote Exception geworfen.
     * @param x ist der geänderte Tisch
     * @return der geänderte Tisch wird auch wieder zurückgegeben und in die Datenbank gespeichert
     * @throws RemoteException
     */
    public Tisch update(Tisch x) throws RemoteException {

        if (compareTInummer(x)) {
            return tiMapper.update(x);
        } else {

            throw new RemoteException("Tisch Nummer ist bereits vergeben, bitte andere wählen");

        }

    }

    /**
     * Die Methode löscht ein Produkt aus der Datenbank, falls dieses in keiner
     * Bestellung mehr vorhanden ist. Sollte das Produkt noch in einer Bestellung vorhanden sein,
     * wird eine RemoteException geworfen.
     * @param x das Produkt, welches gelöscht werden soll
     * @throws RemoteException
     */
    public void delete(Tisch x)throws RemoteException {
        try {
            if (beMapper.existsTisch(x)==false) {
                tiMapper.delete(x);
            }else {
                  throw new RemoteException("Der Tisch ist noch in einer Bestellung enthalten und kann nicht gelöscht werden!");
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Die addbestellung Methode legt eine neue Bestellung in der Datenbank an.
     * Dafür bekommt sie als Parameter die Objekte der Bestellung und des Tisches, welche in der
     * Datenbank angelegt werden sollen.
     * @param ti ist der Tisch, der Bestellung zugwiesen werden soll
     * @param be ist die Bestellung, die angelegt werden soll
     * @return die Bestellung, die angelegt wurde
     */
    public Bestellung addBestellung(Bestellung be, Tisch ti) throws RemoteException {

        return beMapper.insert(be, ti); //Speichert die Bestellung (inkl. Tisch)

    }

    /**
     * Diese Methode speichert eine Änderung bei einem Tisch in der Datenbank
     * ab. Dabei wird überprüft ob die Tisch Nummer bereits vorhanden ist und ansonsten
     * wird die Änderung gespeichert. Sollte die Tisch Nummer bereits vorhanden sein, wird eine Remote Exception geworfen.
     * @param x ist der geänderte Tisch
     * @return der geänderte Tisch wird auch wieder zurückgegeben und in die Datenbank gespeichert
     * @throws RemoteException
     */
    public Bestellung update(Bestellung be, Tisch ti) throws RemoteException {

        return beMapper.update(be, ti); //Bearbeitet die Bestellung (inkl. Tisch)

    }

    /**
     * Die Methode löscht ein Produkt aus der Datenbank, falls dieses in keiner
     * Bestellung mehr vorhanden ist. Sollte das Produkt noch in einer Bestellung vorhanden sein,
     * wird eine RemoteException geworfen.
     * @param x das Produkt, welches gelöscht werden soll
     * @throws RemoteException
     */
    public void delete(Bestellung x)throws RemoteException  {

        zuMapper.deleteByBestellID(x); //Löscht alle Posten einer Bestellung
        beMapper.delete(x);
    }

    /**
     * Die addTisch Methode legt ein neuen Tisch in der Datenbank an.
     * Dafür bekommt sie als Parameter das Objekt des Tischs, welches in der
     * Datenbank angelegt werden soll.
     * Sie überprüft dann ob es die Tisch Nummers bereits gibt. Falls nicht wird es eingetragen, andernfalls wird
     * eine Fehlermeldung angezeigt
     * @param ti ist das Tisch, das angelegt werden soll
     * @return der Tisch, der angelegt wurde, falls die Tisch Nummer noch nicht vergeben wurde
     * @throws RemoteException
     */
    public void addZuordnung(Bestellung be, Produkt pr, int anzahl) throws RemoteException {

        zuMapper.addZuordnung(be, pr, anzahl); //Bearbeitet die Bestellung (inkl. Tisch)

    }



    /**
     * Gibt alle Tische aus der Datenbank zurück
     * @return Vector mit allen eingetragen Tischen der Datenbank
     * @throws RemoteException
     */
    public Vector <Tisch> getAllTische()throws RemoteException  {

        return tiMapper.findAll();
    }

    /**
     * Gibt alle Produkte aus der Datenbank zurück.
     * @return Vector mit allen eingetragen Produkten der Datenbank
     * @throws RemoteException
     */
    public Vector <Produkt> getAllProdukte()throws RemoteException  {

        return prMapper.findAll_produkt();
    }

    /**
     * Gibt alle Speisen aus der Datenbank zurück
     * @return Vector mit allen eingetragen Speisen der Datenbank
     * @throws RemoteException
     */
    public Vector <Produkt> getAllSpeisen()throws RemoteException  {

        return prMapper.findAll_speisen();
    }

    /**
     * Gibt alle Getränke aus der Datenbank zurück
     * @return Vector mit allen eingetragen Getränken der Datenbank
     * @throws RemoteException
     */
    public Vector <Produkt> getAllGetraenke()throws RemoteException  {

        return prMapper.findAll_getraenke();
    }

    
    public int getPRAnzahl_byTime (Timestamp start, Timestamp end, Produkt pr)throws RemoteException {

        return zuMapper.getPRAnzahl_byTime(start, end, pr);
    }


    // Produkt Bezeichnung vergleichen
    public boolean comparePRbezeichnung(Produkt x) throws RemoteException {
        Vector<Produkt> pr = this.prMapper.findAll_produkt();
        Iterator itrPr = pr.iterator();

        while (itrPr.hasNext()) {
            Produkt prTemp = (Produkt) itrPr.next();

            if (prTemp.get_bezeichnung().contentEquals(x.get_bezeichnung())) {
                return false;
            }
        }
        return true;
    }

    // Tisch Nummer vergleichen
    public boolean compareTInummer(Tisch x) throws RemoteException {
        Vector<Tisch> ti = this.tiMapper.findAll();
        Iterator itrTi = ti.iterator();

        while (itrTi.hasNext()) {
            Tisch tiTemp = (Tisch) itrTi.next();

            if (tiTemp.get_tisch_nr() == (x.get_tisch_nr())) {
                return false;
            }
        }
        return true;
    }
}
